package com.linkgie.galaxyframework.security;

import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;

/**
 * 提供后台任务执行的能力；
 */
public interface BackgroundExecutor {

	/**
	 * 创建一个以指定的机构身份执行的任务；
	 * <p>
	 * 在任务的执行过程中，任务线程会切换到指定机构的后台账号上下文执行，可以访问指定机构隔离域的数据；
	 * <br>
	 * 并且在执行完成并返回结果之后，将恢复线程上下文，避免任务线程被复用的时候，当前的登录身份被错误地泄露到其它的任务中；
	 * <p>
	 * 注：根据平台配置的安全策略，如果当前账号不具备权限，则调用此方法会引发异常 {@link ApplicationSecurityException}；
	 *
	 * @param <T>      返回值类型；
	 * @param orgId    机构Id；
	 * @param callable 要执行的任务；
	 * @return
	 */
	<T> FutureTask<T> createOrganizationTask(String orgId, Callable<T> callable);

	/**
	 * 创建一个以指定的机构身份执行的任务；
	 * <p>
	 * 在任务的执行过程中，任务线程会切换到指定机构的后台账号上下文执行，可以访问指定机构隔离域的数据；
	 * <br>
	 * 并且在执行完成并返回结果之后，将恢复线程上下文，避免任务线程被复用的时候，当前的登录身份被错误地泄露到其它的任务中；
	 * <p>
	 * 注：根据平台配置的安全策略，如果当前账号不具备权限，则调用此方法会引发异常 {@link ApplicationSecurityException}；
	 *
	 * @param orgId    机构Id；
	 * @param runnable 要执行的任务；
	 * @return
	 */
	default FutureTask<Void> createOrganizationTask(String orgId, Runnable runnable) {
		return createOrganizationTask(orgId, runnable, null);
	}

	/**
	 * 创建一个以当前上下文执行的任务；
	 * <p>
	 * 在任务的执行过程中，任务线程会切换到当前上下文，以当前上下文的登录身份执行;
	 * <br>
	 * 并且在执行完成并返回结果之后，将恢复线程上下文，避免任务线程被复用的时候，当前的登录身份被错误地泄露到其它的任务中；
	 *
	 * @param <T>      返回值类型；
	 * @param orgId    机构Id；
	 * @param runnable 要执行的任务；
	 * @param result   执行成功后返回的结果；
	 * @return
	 */
	<T> FutureTask<T> createOrganizationTask(String orgId, Runnable runnable, T result);
}
